home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-14 | 39.5 KB | 1,420 lines |
- Newsgroups: comp.sources.misc
- X-UNIX-From: dvadura@watdragon.waterloo.edu
- subject: v15i074: dmake version 3.6 (part 22/25)
- from: Dennis Vadura <dvadura@watdragon.waterloo.edu>
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 15, Issue 74
- Submitted-by: Dennis Vadura <dvadura@watdragon.waterloo.edu>
- Archive-name: dmake-3.6/part22
-
- #!/bin/sh
- # this is part 22 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file dmake.h continued
- #
- CurArch=22
- if test ! -r s2_seq_.tmp
- then echo "Please unpack part 1 first!"
- exit 1; fi
- ( read Scheck
- if test "$Scheck" != $CurArch
- then echo "Please unpack part $Scheck next!"
- exit 1;
- else exit 0; fi
- ) < s2_seq_.tmp || exit 1
- echo "x - Continuing file dmake.h"
- sed 's/^X//' << 'SHAR_EOF' >> dmake.h
- X#define ST_IMPORT 9
- X
- X/* Macro definitions for use inside dmake */
- X#define SET_TOKEN(A, B) (A)->tk_str = (B); (A)->tk_cchar = *(B);\
- X (A)->tk_quote = 1;
- X#define CLEAR_TOKEN(A) *(A)->tk_str = (A)->tk_cchar
- X#define GET_MACRO(A) Get_name(A, Macs, FALSE, NIL(CELL))
- X#define iswhite(C) ((C == ' ') || (C == '\t'))
- X
- X#endif
- X
- SHAR_EOF
- echo "File dmake.h is complete"
- chmod 0440 dmake.h || echo "restore of dmake.h fails"
- echo "x - extracting dmake.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > dmake.c &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dmake.c,v 1.1 90/10/06 12:03:35 dvadura Exp $
- X-- SYNOPSIS -- The main program.
- X--
- X-- DESCRIPTION
- X--
- X-- dmake [-#dbug_string] [ options ]
- X-- [ macro definitions ] [ target ... ]
- X--
- X-- This file contains the main command line parser for the
- X-- make utility. The valid flags recognized are as follows:
- X--
- X-- -f file - use file as the makefile
- X-- -#dbug_string - dump out debugging info, see below
- X--
- X-- options: (can be catenated, ie -irn == -i -r -n)
- X--
- X-- -A - enable AUGMAKE special target mapping
- X-- -i - ignore errors
- X-- -n - trace and print, do not execute commands
- X-- -t - touch, update dates without executing commands
- X-- -T - do not apply transitive closure
- X-- -r - don't use internal rules
- X-- -s - do your work silently
- X-- -S - force Sequential make, overrides -P
- X-- -q - check if target is up to date. Does not
- X-- do anything. Returns 0 if up to date, -1
- X-- otherwise.
- X-- -p - print out a version of the makefile
- X-- -P# - set value of MAXPROCESS
- X-- -e - define environment strings as macros
- X-- -E - as -e but done after parsing makefile
- X-- -u - force unconditional update of target
- X-- -k - make all independent targets even if errors
- X-- -V - print out this make version number
- X-- -v - verbose, print what we are doing, as we do it.
- X-- -M - Microsoft make compatibility, (* disabled *)
- X-- -h - print out usage info
- X-- -x - export macro defs to environment
- X--
- X-- NOTE: - #ddbug_string is only availabe for versions of dmake that
- X-- have been compiled with -DDBUG switch on. Not the case for
- X-- distributed versions. Any such versions must be linked
- X-- together with a version of Fred Fish's debug code.
- X--
- X-- NOTE: - in order to compile the code the include file stddef.h
- X-- must be shipped with the bundled code.
- X--
- X-- AUTHOR
- X-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
- X-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
- X--
- X-- COPYRIGHT
- X-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
- X--
- X-- This program is free software; you can redistribute it and/or
- X-- modify it under the terms of the GNU General Public License
- X-- (version 1), as published by the Free Software Foundation, and
- X-- found in the file 'LICENSE' included with this distribution.
- X--
- X-- This program is distributed in the hope that it will be useful,
- X-- but WITHOUT ANY WARRANTY; without even the implied warrant of
- X-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X-- GNU General Public License for more details.
- X--
- X-- You should have received a copy of the GNU General Public License
- X-- along with this program; if not, write to the Free Software
- X-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X--
- X-- LOG
- X-- $Log: dmake.c,v $
- X * Revision 1.1 90/10/06 12:03:35 dvadura
- X * dmake Release, Version 3.6
- X *
- X*/
- X
- X/* Set this flag to one, and the global variables in vextern.h will not
- X * be defined as 'extern', instead they will be defined as global vars
- X * when this module is compiled. */
- X#define _DEFINE_GLOBALS_ 1
- X
- X#include <ctype.h>
- X#include <stdarg.h>
- X#include "extern.h"
- X#include "alloc.h"
- X#include "db.h"
- X#include "patchlvl.h"
- X#include "version.h"
- X
- X#ifdef HELP
- X#define USAGE \
- X"Usage:\n%s [-AeEhiknpqrsStTuvVx] [-P#] [-f file] [macro[*][+][:]=value ...] [target ...]\n"
- X#define COPYRIGHT "Copyright (c) 1990 by Dennis Vadura"
- X#endif
- X
- Xstatic char *sccid = COPYRIGHT;
- Xstatic char _warn = TRUE; /* warnings on by default */
- X
- Xstatic void _do_VPATH();
- Xstatic void _do_ReadEnvironment();
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X char* fil_name = NIL(char);
- X char* cmdmacs;
- X char* targets;
- X FILE* mkfil;
- X int ex_val;
- X int m_export;
- X HASHPTR hp;
- X
- X DB_ENTER("main");
- X
- X /* Initialize Global variables to their default values */
- X Prolog(argc, argv);
- X Create_macro_vars();
- X Catch_signals(Quit);
- X
- X Def_macro( "MAKECMD", Pname, M_PRECIOUS|M_NOEXPORT );
- X Pname = basename(Pname);
- X
- X DB_PROCESS(Pname);
- X (void) setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* stdout line buffered */
- X
- X Continue = FALSE;
- X Get_env = FALSE;
- X Force = FALSE;
- X Target = FALSE;
- X If_expand = FALSE;
- X Listing = FALSE;
- X Readenv = FALSE;
- X Rules = TRUE;
- X Trace = FALSE;
- X Touch = FALSE;
- X Check = FALSE;
- X Microsoft = FALSE;
- X Verbose = FALSE;
- X Makemkf = FALSE;
- X m_export = FALSE;
- X cmdmacs = NIL(char);
- X targets = NIL(char);
- X
- X Transitive = TRUE;
- X Nest_level = 0;
- X Line_number = 0;
- X
- X while( --argc > 0 ) {
- X register char *p;
- X char *q;
- X
- X if( *(p = *++argv) == '-' ) {
- X if( p[1] == '\0' ) Fatal("Missing option letter");
- X
- X /* copy options to Buffer for $(MFLAGS), strip 'f' */
- X q = strchr(Buffer, 0);
- X while (*p != 0)
- X if( (*q++ = *p++) == 'f' ) q--;
- X
- X if( *(q-1) == '-' )
- X q--;
- X else
- X *q++ = ' ';
- X
- X *q = 0;
- X
- X for( p = *argv+1; *p; p++) switch (*p) {
- X case 'f':
- X if( fil_name == NIL(char) ) {
- X if( *++argv != NIL(char) ) {
- X fil_name = *argv;
- X argc--;
- X } else
- X Fatal("No file name for -f");
- X } else
- X Fatal("Only one `-f file' allowed");
- X break;
- X
- X case 'k': Continue = TRUE; break;
- X case 'p': Listing = TRUE; break;
- X case 'r': Rules = FALSE; break;
- X case 'n': Trace = TRUE; break;
- X case 't': Touch = TRUE; break;
- X case 'q': Check = TRUE; break;
- X case 'u': Force = TRUE; break;
- X case 'v': Verbose = TRUE; break;
- X case 'x': m_export = TRUE; break;
- X case 'T': Transitive = FALSE; break;
- X case 'e': Get_env = 'e'; break;
- X case 'E': Get_env = 'E'; break;
- X
- X case 'V': Version(); Quit(NIL(CELL)); break;
- X case 'A': Def_macro("AUGMAKE", "y", M_EXPANDED); break;
- X case 'i': Def_macro(".IGNORE", "y", M_EXPANDED); break;
- X case 's': Def_macro(".SILENT", "y", M_EXPANDED); break;
- X case 'S': Def_macro(".SEQUENTIAL", "y", M_EXPANDED); break;
- X
- X case 'P':
- X if( p[1] ) {
- X Def_macro( "MAXPROCESS", p+1, M_MULTI|M_EXPANDED );
- X p += strlen(p)-1;
- X }
- X else
- X Fatal( "Missing number for -P flag" );
- X break;
- X
- X#ifdef HELP
- X case 'h': Usage(); Quit(NIL(CELL)); break;
- X#endif
- X#ifdef DBUG
- X case '#':
- X DB_PUSH(p+1);
- X p += strlen(p)-1;
- X break;
- X#endif
- X
- X default:
- X fprintf(stderr, USAGE, Pname);
- X Quit(NIL(CELL));
- X break;
- X }
- X }
- X else if( (q = strchr(p, '=')) != NIL(char) ) {
- X cmdmacs = _stradd( cmdmacs, _strdup(p), TRUE );
- X Parse_macro( p, (strchr(p,'+')==NIL(char))?M_PRECIOUS:M_DEFAULT );
- X }
- X else {
- X register CELLPTR cp;
- X targets = _stradd( targets, _strdup(p), TRUE );
- X Add_fringe(cp = Def_cell(p, NIL(CELL)));
- X cp->ce_flag |= F_TARGET;
- X Target = TRUE;
- X }
- X }
- X
- X Def_macro( "MAKEMACROS", cmdmacs, M_PRECIOUS|M_NOEXPORT );
- X Def_macro( "MAKETARGETS", targets, M_PRECIOUS|M_NOEXPORT );
- X if( cmdmacs != NIL(char) ) FREE(cmdmacs);
- X if( targets != NIL(char) ) FREE(targets);
- X
- X Def_macro( "MFLAGS", Buffer, M_PRECIOUS|M_NOEXPORT );
- X Def_macro( "%", "$@", M_PRECIOUS|M_NOEXPORT );
- X
- X if( *Buffer ) Def_macro( "MAKEFLAGS", Buffer+1, M_PRECIOUS|M_NOEXPORT );
- X
- X _warn = FALSE; /* disable warnings for builtin rules */
- X ex_val = Target; /* make sure we don't mark any */
- X Target = TRUE; /* of the default rules as */
- X Make_rules(); /* potential targets */
- X _warn = TRUE;
- X
- X if( Rules ) {
- X /* order of precedence is:
- X *
- X * MAKESTARTUP from command line (precious is marked)
- X * MAKESTARTUP from environment
- X * MAKESTARTUP from builtin rules (not precious)
- X */
- X char *fname;
- X
- X if( ((hp = GET_MACRO("MAKESTARTUP")) != NIL(HASH)) &&
- X (hp->ht_flag & M_PRECIOUS) &&
- X (mkfil=Openfile(fname=hp->ht_value, FALSE)) != NIL(FILE) ||
- X (mkfil=Openfile(fname=Read_env_string("MAKESTARTUP"), FALSE)) != NIL(FILE) ||
- X hp != NIL(HASH) &&
- X (mkfil=Openfile(fname=hp->ht_value, FALSE)) != NIL(FILE) )
- X {
- X Parse(mkfil);
- X mkfil = NIL(FILE);
- X }
- X else
- X Fatal( "configuration file `%s' not found", fname );
- X }
- X
- X Target = ex_val;
- X
- X if( Get_env == 'e' ) _do_ReadEnvironment();
- X
- X if( fil_name != NIL(char) )
- X mkfil = Openfile( fil_name, TRUE );
- X else {
- X /* Search .MAKEFILES dependent list looking for a makefile.
- X */
- X register CELLPTR cp;
- X register LINKPTR lp;
- X
- X cp = Def_cell( ".MAKEFILES", NIL(CELL) );
- X
- X if( (lp = cp->CE_PRQ) != NIL(LINK) ) {
- X int s_n, s_t, s_q;
- X
- X s_n = Trace;
- X s_t = Touch;
- X s_q = Check;
- X
- X Trace = Touch = Check = FALSE;
- X Makemkf = Wait_for_completion = TRUE;
- X mkfil = NIL(FILE);
- X
- X for(; lp != NIL(LINK) && mkfil == NIL(FILE); lp=lp->cl_next) {
- X mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE );
- X
- X if( mkfil == NIL(FILE) &&
- X Make(lp->cl_prq, lp->cl_prq->CE_HOW, NIL(CELL)) != -1 )
- X mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE );
- X }
- X
- X Trace = s_n;
- X Touch = s_t;
- X Check = s_q;
- X Makemkf = Wait_for_completion = FALSE;
- X }
- X }
- X
- X if( mkfil != NIL(FILE) ) {
- X char *f = Filename();
- X char *p;
- X
- X if( strcmp(f, "stdin") == 0 ) f = "-";
- X p = _stradd( "-f", f, FALSE );
- X Def_macro( "MAKEFILE", p, M_PRECIOUS|M_NOEXPORT );
- X Parse( mkfil );
- X }
- X else if( !Rules )
- X Fatal( "No `makefile' present" );
- X
- X if( Nest_level ) Fatal( "Missing .END for .IF" );
- X if( Get_env == 'E' ) _do_ReadEnvironment();
- X
- X _do_VPATH(); /* kludge it up with .SOURCE */
- X
- X if( Listing ) Dump(); /* print out the structures */
- X if( Trace ) Glob_attr &= ~A_SILENT; /* make sure we see the trace */
- X
- X if( !Target )
- X Fatal( "No target" );
- X else {
- X Check_circle( Fringe_hd );
- X Check_circle_dfa();
- X }
- X
- X TALLOC( Start_dir.ce_name, 1, HASH );
- X Start_dir.CE_NAME = ".SETDIR";
- X Push_dir( &Start_dir, Glob_attr & A_IGNORE );
- X
- X if( m_export ) {
- X int i;
- X
- X for( i=0; i<HASH_TABLE_SIZE; ++i ) {
- X char *tmpstr = hp->ht_value;
- X
- X if( tmpstr == NIL(char) ) tmpstr = "";
- X if( !(hp->ht_flag & M_NOEXPORT) &&
- X Write_env_string(hp->ht_name, tmpstr) != 0 )
- X Warning( "Could not export %s", hp->ht_name );
- X }
- X }
- X
- X if( Buffer != NIL(char) ) FREE( Buffer );
- X if( Trace ) Def_macro(".SEQUENTIAL", "y", M_EXPANDED);
- X if( Glob_attr & A_SEQ ) Def_macro( "MAXPROCESS", "1", M_EXPANDED|M_FORCE );
- X
- X ex_val = Make_targets();
- X
- X Pop_dir( (Glob_attr & A_IGNORE) != 0 );
- X Clear_signals();
- X Epilog(ex_val); /* Does not return -- EVER */
- X}
- X
- X
- Xstatic void
- X_do_ReadEnvironment()
- X{
- X t_attr saveattr = Glob_attr;
- X
- X Glob_attr |= A_SILENT;
- X ReadEnvironment();
- X Glob_attr = saveattr;
- X}
- X
- X
- Xstatic void
- X_do_VPATH()
- X{
- X HASHPTR hp;
- X char *_rl[2];
- X extern char **Rule_tab;
- X
- X hp = GET_MACRO("VPATH");
- X if( hp == NIL(HASH) ) return;
- X
- X _rl[0] = ".SOURCE :^ $(VPATH:s/:/ /)";
- X _rl[1] = NIL(char);
- X
- X Rule_tab = _rl;
- X Parse( NIL(FILE) );
- X}
- X
- X
- X/* The file table and pointer to the next FREE slot for use by both
- X Openfile and Closefile. Each open stacks the new file onto the open
- X file stack, and a corresponding close will close the passed file, and
- X return the next file on the stack. The maximum number of nested
- X include files is limited by the value of MAX_INC_DEPTH */
- X
- Xstatic struct {
- X FILE *file; /* file pointer */
- X char *name; /* name of file */
- X int numb; /* line number */
- X} ftab[ MAX_INC_DEPTH ];
- X
- Xstatic int next_file_slot = 0;
- X
- X/* Set the proper macro value to reflect the depth of the .INCLUDE directives.
- X */
- Xstatic void
- X_set_inc_depth()
- X{
- X char buf[10];
- X sprintf( buf, "%d", next_file_slot-1 );
- X Def_macro( "INCDEPTH", buf, M_MULTI|M_NOEXPORT );
- X}
- X
- X
- XFILE *
- XOpenfile(name, err)/*
- X=====================
- X This routine opens a file for input.
- X If the file name is `-' then it returns standard input.
- X The file is pushed onto the open file stack. */
- Xchar *name;
- Xint err;
- X{
- X FILE *fil;
- X
- X DB_ENTER("Openfile");
- X
- X if( name == NIL(char) || !*name )
- X if( !err )
- X DB_RETURN(NIL(FILE));
- X else
- X Fatal( "Openfile: NIL filename" );
- X
- X if( next_file_slot == MAX_INC_DEPTH )
- X Fatal( "Too many open files. Max nesting level is %d.", MAX_INC_DEPTH);
- X
- X DB_PRINT( "io", ("Opening file [%s], in slot %d", name, next_file_slot) );
- X
- X if( strcmp("-", name) == 0 ) {
- X name = "stdin";
- X fil = stdin;
- X }
- X else
- X fil = fopen( name, "r" );
- X
- X if( fil == NIL(FILE) ) {
- X if( err )
- X Fatal( "File %s not found", name );
- X }
- X else {
- X ftab[next_file_slot].file = fil;
- X ftab[next_file_slot].numb = Line_number;
- X ftab[next_file_slot++].name = _strdup(name);
- X Line_number = 0;
- X _set_inc_depth();
- X }
- X
- X DB_RETURN(fil);
- X}
- X
- XFILE *
- XClosefile()/*
- X=============
- X This routine is used to close the last file opened. This forces make
- X to open files in a last open first close fashion. It returns the
- X file pointer to the next file on the stack, and NULL if the stack is empty.*/
- X{
- X DB_ENTER("Closefile");
- X
- X if( !next_file_slot )
- X DB_RETURN( NIL(FILE) );
- X
- X if( ftab[--next_file_slot].file != stdin ) {
- X DB_PRINT( "io", ("Closing file in slot %d", next_file_slot) );
- X fclose( ftab[next_file_slot].file );
- X FREE( ftab[next_file_slot].name );
- X _set_inc_depth();
- X }
- X
- X if( next_file_slot > 0 ) {
- X Line_number = ftab[next_file_slot].numb;
- X DB_RETURN( ftab[next_file_slot-1].file );
- X }
- X else
- X Line_number = 0;
- X
- X DB_RETURN( NIL(FILE) );
- X}
- X
- X
- Xchar *
- XFilename()/*
- X============
- X Return name of file on top of stack */
- X{
- X return( next_file_slot==0 ? NIL(char) : ftab[next_file_slot-1].name );
- X}
- X
- X/*
- X** print error message from variable arg list
- X*/
- X
- Xstatic int errflg = TRUE;
- Xstatic int warnflg = FALSE;
- X
- Xstatic void
- Xerrargs(fmt, args)
- Xchar *fmt;
- Xva_list args;
- X{
- X int warn = _warn && warnflg && !(Glob_attr & A_SILENT);
- X
- X if( errflg || warn ) {
- X char *f = Filename();
- X
- X fprintf( stderr, "%s: ", Pname );
- X if( f != NIL(char) ) fprintf(stderr, "%s: line %d: ", f, Line_number);
- X
- X if( errflg )
- X fprintf(stderr, "Error -- ");
- X else if( warn )
- X fprintf(stderr, "Warning -- ");
- X
- X vfprintf( stderr, fmt, args );
- X putc( '\n', stderr );
- X if( errflg && !Continue ) Quit( NIL(CELL) );
- X }
- X}
- X
- X/*
- X** Print error message and abort
- X*/
- Xint
- XFatal(fmt, va_alist)
- Xchar *fmt;
- Xva_dcl;
- X{
- X va_list args;
- X
- X va_start(args, fmt);
- X Continue = FALSE;
- X errargs(fmt, args);
- X va_end(args);
- X}
- X
- X/*
- X** error message and exit (unless -k)
- X*/
- Xint
- XError(fmt, va_alist)
- Xchar* fmt;
- Xva_dcl;
- X{
- X va_list args;
- X
- X va_start(args, fmt);
- X errargs(fmt, args);
- X va_end(args);
- X}
- X
- X
- X/*
- X** non-fatal message
- X*/
- Xint
- XWarning(fmt, va_alist)
- Xchar *fmt;
- Xva_dcl;
- X{
- X va_list args;
- X
- X va_start(args, fmt);
- X warnflg = TRUE;
- X errflg = FALSE;
- X errargs(fmt, args);
- X errflg = TRUE;
- X warnflg = FALSE;
- X va_end(args);
- X}
- X
- X
- Xvoid
- XNo_ram()
- X{
- X Fatal( "No more memory" );
- X}
- X
- X
- X#ifdef HELP
- XUsage()
- X{
- X printf(USAGE, Pname);
- X puts(" -P# - set max number of child processes for parallel make");
- X puts(" -f file - use file as the makefile\n");
- X
- X puts("Options: (can be catenated, ie -irn == -i -r -n)");
- X puts(" -A - enable AUGMAKE special target mapping");
- X puts(" -e - define environment strings as macros");
- X puts(" -E - same as -e but done after parsing makefile");
- X puts(" -h - print out usage info");
- X puts(" -i - ignore errors");
- X puts(" -k - make independent targets, even if errors");
- X puts(" -n - trace and print, do not execute commands");
- X puts(" -p - print out a version of the makefile");
- X puts(" -q - check if target is up to date. Does not do");
- X puts(" anything. Returns 0 if up to date, 1 otherwise");
- X puts(" -r - don't use internal rules");
- X puts(" -s - do your work silently");
- X puts(" -S - disable parallel (force sequential) make, overrides -P");
- X puts(" -t - touch, update time stamps without executing commands");
- X puts(" -T - do not apply transitive closure");
- X puts(" -u - force unconditional update of target");
- X puts(" -v - verbose, print out what we are doing");
- X puts(" -V - print out version number");
- X puts(" -x - export macro values to environment");
- X}
- X#endif
- X
- X
- XVersion()
- X{
- X extern char **Rule_tab;
- X char **p;
- X
- X printf("%s - %s, ", Pname, COPYRIGHT);
- X printf("Version %s, Patch Level %d\n\n", VERSION, PATCHLEVEL);
- X
- X puts("Default Configuration:");
- X for (p=Rule_tab; *p != NIL(char); p++)
- X printf("\t%s\n", *p);
- X}
- SHAR_EOF
- chmod 0440 dmake.c || echo "restore of dmake.c fails"
- echo "x - extracting dag.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > dag.c &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dag.c,v 1.1 90/10/06 12:03:33 dvadura Exp $
- X-- SYNOPSIS -- Routines to construct the internal dag.
- X--
- X-- DESCRIPTION
- X-- This file contains all the routines that are responsible for
- X-- defining and manipulating all objects used by the make facility.
- X--
- X-- AUTHOR
- X-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
- X-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
- X--
- X-- COPYRIGHT
- X-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
- X--
- X-- This program is free software; you can redistribute it and/or
- X-- modify it under the terms of the GNU General Public License
- X-- (version 1), as published by the Free Software Foundation, and
- X-- found in the file 'LICENSE' included with this distribution.
- X--
- X-- This program is distributed in the hope that it will be useful,
- X-- but WITHOUT ANY WARRANTY; without even the implied warrant of
- X-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X-- GNU General Public License for more details.
- X--
- X-- You should have received a copy of the GNU General Public License
- X-- along with this program; if not, write to the Free Software
- X-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X--
- X-- LOG
- X-- $Log: dag.c,v $
- X * Revision 1.1 90/10/06 12:03:33 dvadura
- X * dmake Release, Version 3.6
- X *
- X*/
- X
- X#include <ctype.h>
- X#include "extern.h"
- X#include "alloc.h"
- X#include "db.h"
- X
- X
- XHASHPTR
- XGet_name( name, tab, define, dir )/*
- X====================================
- X Look to see if the name is defined, if it is then return
- X a pointer to its node, if not return NIL(HASH).
- X If define is TRUE and the name is not found it will be added. */
- X
- Xchar *name; /* name we are looking for */
- XHASHPTR *tab; /* the hash table to look in */
- Xint define; /* TRUE => add to table */
- XCELLPTR dir;
- X{
- X register HASHPTR hp;
- X register char *p;
- X uint16 hv;
- X uint32 hash_key;
- X
- X DB_ENTER( "Get_name" );
- X DB_PRINT( "name", ("Looking for %s", name) );
- X
- X hv = Hash( name, &hash_key );
- X
- X for( hp = tab[ hv ]; hp != NIL(HASH); hp = hp->ht_next )
- X if( hp->ht_hash == hash_key &&
- X (tab != Defs || ((tab == Defs) && (hp->CP_ROOT == dir))) &&
- X !strcmp(hp->ht_name, name) )
- X break;
- X
- X if( hp == NIL(HASH) && define ) {
- X /* Check to make sure that CELL name contains only printable chars */
- X for( p=name; *p; p++ )
- X if( !isprint(*p) )
- X Fatal( "Name contains non-printable character [0x%02x]", *p );
- X
- X TALLOC( hp, 1, HASH ); /* allocate a cell and add it in */
- X
- X if( tab == Defs ) hp->CP_ROOT = dir;
- X hp->ht_name = _strdup( name );
- X hp->ht_hash = hash_key;
- X hp->ht_next = tab[ hv ];
- X tab[ hv ] = hp;
- X
- X DB_PRINT( "name", ("Adding %s", name) );
- X }
- X
- X DB_PRINT( "name",("Returning: [%s,%lu]",
- X (hp == NIL(HASH)) ? "":hp->ht_name, hv) );
- X DB_RETURN( hp );
- X}
- X
- X
- X
- XHASHPTR
- XDef_macro( name, value, flags )/*
- X=================================
- X This routine is used to define a macro, and it's value.
- X The flags indicates if it is a permanent macro or if it's value
- X can be redefined. A flags of M_PRECIOUS means it is a precious
- X macro and cannot be further redefined. If the flags flag also
- X contains the M_MULTI bit it means that the macro can be redefined
- X multiple times and no warning of the redefinitions should be issued.
- X Once a macro's VAR flags are set they are preserved through all future
- X macro definitions.
- X
- X Macro definitions that have one of the variable bits set are treated
- X specially. In each case the hash table entry var field points at the
- X global variable that can be set by assigning to the macro.
- X
- X bit valued global vars must be computed when the macro value is changed.
- X char valued global vars must have the first char of ht_value copied to
- X them. string valued global vars have the same value as ht_value and should
- X just have the new value of ht_value copied to them. */
- X
- Xchar *name; /* macro name to define */
- Xchar *value; /* macro value to set */
- Xint flags; /* initial ht_flags */
- X{
- X register HASHPTR hp;
- X register char *p, *q;
- X
- X DB_ENTER( "Def_macro" );
- X DB_PRINT( "mac", ("Defining macro %s = %s, %x", name, value, flags) );
- X
- X /* check to see if name is in the table, if so then just overwrite
- X the previous definition. Otherwise allocate a new node, and
- X stuff it in the hash table, at the front of any linked list */
- X
- X if( Readenv ) flags |= M_LITERAL;
- X
- X hp = Get_name( name, Macs, TRUE, NIL(CELL) );
- X
- X if( (hp->ht_flag & M_PRECIOUS) && !(flags & M_FORCE) ) {
- X Warning( "Macro `%s' cannot be redefined", name );
- X DB_RETURN( hp );
- X }
- X
- X if( hp->ht_value != NIL(char) ) FREE( hp->ht_value );
- X
- X if( (hp->ht_flag & M_USED) && !((flags | hp->ht_flag) & M_MULTI) )
- X Warning( "Macro `%s' redefined after use", name );
- X
- X if( (value != NIL(char)) && (*value) ) {
- X /* strip out any \<nl> combinations where \ is the current CONTINUATION
- X * char */
- X
- X for( p = value; (p = strchr(p, CONTINUATION_CHAR)) != NIL(char); )
- X if( p[1] == '\n' )
- X strcpy( p, p+2 );
- X else
- X p++;
- X
- X if( !(flags & M_LITERAL) ) {
- X p = _strdup( _strspn( value, " \t" ) ); /* strip white space before */
- X /* ... and after value */
- X if( *p ) {
- X for(q=p+strlen(p)-1; ((*q == ' ')||(*q == '\t')); q--);
- X *++q = '\0';
- X }
- X flags &= ~M_LITERAL;
- X }
- X else
- X p = _strdup( value ); /* take string literally */
- X
- X if( !*p ) { /* check if result is "" */
- X FREE( p );
- X p = NIL(char);
- X flags |= M_EXPANDED;
- X }
- X else if( *_strpbrk( p, "${}" ) == '\0' )
- X flags |= M_EXPANDED;
- X
- X hp->ht_value = p;
- X }
- X else
- X hp->ht_value = NIL(char);
- X
- X /* Assign the hash table flag less the M_MULTI flag, it is used only
- X * to silence the warning. But carry it over if it was previously
- X * defined in ht_flag, as this is a permanent M_MULTI variable. */
- X
- X hp->ht_flag = (flags & ~(M_MULTI|M_FORCE)) |
- X (hp->ht_flag & (M_VAR_MASK | M_MULTI));
- X
- X /* Check for macro variables and make the necessary adjustment in the
- X * corresponding global variables */
- X
- X if( hp->ht_flag & M_VAR_MASK )
- X if( !(flags & M_EXPANDED) )
- X Error( "Macro variables must be assigned with :=" );
- X else switch( hp->ht_flag & M_VAR_MASK ) /* only one var type per var */
- X {
- X case M_VAR_STRING:
- X *hp->MV_SVAR = hp->ht_value;
- X break;
- X
- X case M_VAR_CHAR:
- X *hp->MV_CVAR = (hp->ht_value == NIL(char)) ? '\0':*hp->ht_value;
- X break;
- X
- X case M_VAR_INT: {
- X int tvalue;
- X if( hp->MV_IVAR == NIL(int) ) break; /* first time */
- X
- X tvalue = atoi(hp->ht_value);
- X if( hp->MV_IVAR == &Buffer_size ) {
- X /* If Buffer_size is modified then make sure you change the
- X * size of the real buffer as well. */
- X tvalue = (tvalue < (BUFSIZ-2)) ? BUFSIZ : tvalue+2;
- X if( Buffer_size == tvalue ) break;
- X if( Buffer ) FREE(Buffer);
- X if((Buffer=MALLOC(tvalue, char)) == NIL(char)) No_ram();
- X *Buffer = '\0';
- X }
- X *hp->MV_IVAR = tvalue;
- X
- X if( hp->MV_IVAR == &Max_proc || hp->MV_IVAR == &Max_proclmt ) {
- X if( tvalue < 1 )
- X Fatal( "Process limit value must be > 1" );
- X
- X if( Max_proc > Max_proclmt )
- X Fatal( "Specified # of processes exceeds limit of [%d]",
- X Max_proclmt );
- X }
- X } break;
- X
- X case M_VAR_BIT:
- X /* Bit variables are set to 1 if ht_value is not NULL and 0
- X * otherwise */
- X
- X if( hp->ht_value == NIL(char) )
- X *hp->MV_BVAR &= ~hp->MV_MASK;
- X else
- X *hp->MV_BVAR |= hp->MV_MASK;
- X break;
- X }
- X
- X DB_RETURN( hp );
- X}
- X
- X
- X
- XCELLPTR
- XDef_cell( name, dir )/*
- X=======================
- X Take a string passed in and define it as a cell
- X If the cell exists then return a pointer to it. */
- Xchar *name;
- XCELLPTR dir;
- X{
- X register HASHPTR hp;
- X register CELLPTR cp;
- X register CELLPTR lib;
- X char *member;
- X char *end;
- X
- X DB_ENTER( "Def_cell" );
- X
- X /* Check to see if the cell is a member of the form lib(member) or
- X * lib((symbol)) and handle the cases appropriately.
- X * What we do is we look at the target, if it is of the above two
- X * forms we get the lib, and add the member/symbol to the list of
- X * prerequisites for the library. If this is a symbol name def'n
- X * we additionally add the attribute A_SYMBOL, so that stat can
- X * try to do the right thing. */
- X
- X if( ((member = strchr(name, '(')) != NIL(char)) &&
- X ((end = strrchr(member, ')')) != NIL(char)) &&
- X (member > name) && (member[-1] != '$') &&
- X (end > member+1) && (end[1] == '\0') )
- X {
- X *member++ = *end = '\0';
- X
- X if( (*member == '(') && (member[strlen(member)-1] == ')') ) {
- X member[ strlen(member)-1 ] = '\0';
- X cp = Def_cell( member+1, dir );
- X cp->ce_attr |= A_SYMBOL;
- X }
- X else
- X cp = Def_cell( member, dir );
- X
- X lib = Def_cell( name, dir );
- X
- X if( lib->CE_HOW == NIL(HOW) ) TALLOC( lib->CE_HOW, 1, HOW );
- X
- X Add_prerequisite( lib->CE_HOW, cp, FALSE );
- X lib->ce_attr |= A_LIBRARY | A_COMPOSITE;
- X
- X if( !Def_targets ) cp = lib;
- X }
- X else {
- X hp = Get_name( name, Defs, TRUE, dir );/* get the name from hash table */
- X
- X if( hp->CP_OWNR == NIL(CELL) ) /* was it previously defined */
- X { /* NO, so define a new cell */
- X DB_PRINT( "cell", ("Defining cell [%s]", name) );
- X
- X TALLOC( cp, 1, CELL );
- X hp->CP_OWNR = cp;
- X cp->ce_name = hp;
- X }
- X else /* YES, so return the old cell */
- X {
- X DB_PRINT( "cell", ("Getting cell [%s]", hp->ht_name) );
- X cp = hp->CP_OWNR;
- X }
- X }
- X
- X DB_RETURN( cp );
- X}
- X
- X
- X
- X
- XLINKPTR
- XAdd_prerequisite( how, cell, head )/*
- X=====================================
- X Add a dependency node to the dag. It adds it to the prerequisites,
- X if any, of the cell and makes certain they are in linear order.
- X If head == 1, then add to head of the prerequisite list, else
- X add to tail. */
- X
- XHOWPTR how;
- XCELLPTR cell;
- Xint head;
- X{
- X register LINKPTR lp, tlp;
- X
- X DB_ENTER( "Add_prerequisite" );
- X DB_PRINT( "cell", ("Defining prerequisite %s", cell->CE_NAME) );
- X
- X if( (cell->ce_flag & (F_MAGIC | F_PERCENT)) )
- X Fatal( "Special target [%s] cannot be a prerequisite",
- X cell->CE_NAME );
- X
- X if( how->hw_prq == NIL(LINK) ) { /* it's the first one */
- X TALLOC( lp, 1, LINK );
- X lp->cl_prq = cell;
- X how->hw_prq = lp;
- X }
- X else { /* search the list, checking for duplicates */
- X for( lp = how->hw_prq;
- X (lp->cl_next != NIL(LINK)) && (lp->cl_prq != cell);
- X lp = lp->cl_next );
- X
- X /* If the cell is not found and we are at the last cell in the list,
- X * allocate a new cell and place it into the list, insert it at the
- X * head if head == 1, else we add it to the end. */
- X
- X if( (lp->cl_prq != cell) ) {
- X TALLOC( tlp, 1, LINK );
- X tlp->cl_prq = cell;
- X
- X if( head ) {
- X tlp->cl_next = how->hw_prq;
- X how->hw_prq = tlp;
- X }
- X else
- X lp->cl_next = tlp;
- X
- X lp = tlp;
- X }
- X }
- X
- X DB_RETURN( lp );
- X}
- X
- X
- X
- Xvoid
- XClear_prerequisites( how )/*
- X============================
- X Clear out the list of prerequisites, freeing all of the LINK nodes,
- X and setting the list to NULL */
- XHOWPTR how;
- X{
- X LINKPTR lp, tlp;
- X
- X DB_ENTER( "Clear_prerequisites" );
- X DB_PRINT( "cell", ("Nuking prerequisites") );
- X
- X if( how == NIL(HOW) ) { DB_VOID_RETURN; }
- X
- X for( lp=how->hw_prq; lp != NIL(LINK); lp=tlp ) {
- X tlp=lp->cl_next;
- X FREE( lp );
- X }
- X
- X how->hw_prq = NIL(LINK);
- X
- X DB_VOID_RETURN;
- X}
- X
- X
- X
- Xvoid
- XAdd_fringe( cp )/*
- X================== Take the cell pointed to by cp and put it at the end
- X of the fringe of targets */
- XCELLPTR cp;
- X{
- X DB_ENTER( "Add_fringe" );
- X
- X if( !(cp->ce_attr & A_FRINGE) ) {
- X DB_PRINT( "cell", ("Adding to fringe %s", cp->ce_name->ht_name) );
- X
- X if( Fringe_hd == NIL(LINK) ) {
- X TALLOC( Fringe_hd, 1, LINK );
- X Fringe_tl = Fringe_hd;
- X }
- X else if( Fringe_tl != NIL(LINK) ) {
- X TALLOC( Fringe_tl->cl_next, 1, LINK );
- X Fringe_tl = Fringe_tl->cl_next;
- X }
- X
- X Fringe_tl->cl_prq = cp;
- X cp->ce_attr |= A_FRINGE;
- X }
- X
- X DB_VOID_RETURN;
- X}
- X
- X
- X
- X
- Xvoid
- XCheck_circle( lp )/*
- X====================
- X Check for circular definitions in the make graph */
- XLINKPTR lp;
- X{
- X for( ; lp != NIL(LINK); lp = lp->cl_next )
- X if( Test_circle( lp->cl_prq, FALSE ) )
- X Fatal( "Detected circular dependency in graph at [%s]",
- X lp->cl_prq->CE_NAME );
- X}
- X
- X
- X
- X
- Xint
- XTest_circle( cp, meta )/*
- X=========================
- X Actually run through the graph */
- XCELLPTR cp;
- Xint meta;
- X{
- X int res = 0;
- X DB_ENTER( "Test_circle" );
- X DB_PRINT( "tc", ("checking [%s]", cp->CE_NAME) );
- X
- X if( cp->ce_flag & F_MARK )
- X DB_RETURN( (cp->ce_attr & A_LIBRARY) ? 0 : 1 );
- X
- X cp->ce_flag |= F_MARK;
- X
- X if( meta ) {
- X register EDGEPTR ep;
- X
- X if( cp->CE_EDGES != NIL(EDGE) ) {
- X EDGEPTR es;
- X
- X ep = es = cp->CE_EDGES;
- X do {
- X if( ep->ed_prq != NIL(CELL) && ep->ed_prq->ce_flag & F_DFA )
- X res = Test_circle( ep->ed_prq, TRUE );
- X ep = ep->ed_next;
- X }
- X while( ep != es && !res );
- X }
- X }
- X else {
- X register LINKPTR tcp;
- X
- X if( cp->CE_HOW != NIL(HOW) )
- X for( tcp = cp->CE_HOW->hw_prq; !res && tcp != NIL(LINK);
- X tcp = tcp->cl_next )
- X if( tcp->cl_prq != cp ) res = Test_circle( tcp->cl_prq, FALSE );
- X }
- X
- X cp->ce_flag ^= F_MARK;
- X DB_RETURN( res );
- X}
- X
- X
- X
- X
- XSTRINGPTR
- XDef_recipe( rcp, sp, white_too, no_check )/*
- X=============================================
- X Take the recipe and add it to the list of recipes
- X pointed to by sp. sp points to the last element.
- X return a pointer to the new recipe. If white_too == TRUE add the
- X recipe even if it contains only white space.
- X If no_check is true then don't look for -@ at the start of the
- X recipe line. */
- Xchar *rcp;
- XSTRINGPTR sp;
- Xint white_too;
- Xint no_check;
- X{
- X register STRINGPTR nsp;
- X register char *rp;
- X t_attr flag;
- X int done;
- X
- X DB_ENTER( "Def_recipe" );
- X DB_PRINT( "rul", ("Defining recipe %s", rcp) );
- X
- X if( !white_too ) rcp = _strspn( rcp, " \t" );
- X if( (rcp == NIL(char)) || (*rcp == 0 && !white_too) )
- X DB_RETURN( sp ); /* return last recipe when new recipe not added */
- X
- X rp = no_check ? rcp : _strspn( rcp, " \t@-+%" );
- X
- X TALLOC( nsp, 1, STRING );
- X nsp->st_string = _strdup( rp );
- X
- X if( sp != NIL(STRING) ) sp->st_next = nsp;
- X nsp->st_next = NIL(STRING);
- X
- X if( no_check ) DB_RETURN( nsp );
- X
- X for( flag = A_DEFAULT, rp = rcp, done = FALSE; !done; )
- X switch( *rp++ )
- X {
- X case '@' : flag |= A_SILENT; break;
- X case '-' : flag |= A_IGNORE; break;
- X case '+' : flag |= A_SHELL; break;
- X case '%' : flag |= A_SWAP; break;
- X
- X case ' ' :
- X case '\t': break;
- X
- X default: done = TRUE; break;
- X }
- X
- X nsp->st_attr |= flag;
- X
- X DB_RETURN( nsp );
- X}
- SHAR_EOF
- chmod 0440 dag.c || echo "restore of dag.c fails"
- echo mkdir - common
- mkdir common
- echo "x - extracting common/stdmacs.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > common/stdmacs.h &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/common/RCS/stdmacs.h,v 1.1 90/10/06 12:04:47 dvadura Exp $
- X-- SYNOPSIS -- general use macros.
- X--
- X-- DESCRIPTION
- X-- ANSI macro relies on the fact that it can be replaced by (), or by
- X-- its value, where the value is one value due to the preprocessors
- X-- handling of arguments that are surrounded by ()'s as a single
- X-- argument.
- X--
- X-- AUTHOR
- X-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
- X-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
- X--
- X-- COPYRIGHT
- X-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
- X--
- X-- This program is free software; you can redistribute it and/or
- X-- modify it under the terms of the GNU General Public License
- X-- (version 1), as published by the Free Software Foundation, and
- X-- found in the file 'LICENSE' included with this distribution.
- X--
- X-- This program is distributed in the hope that it will be useful,
- X-- but WITHOUT ANY WARRANTY; without even the implied warrant of
- X-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X-- GNU General Public License for more details.
- X--
- X-- You should have received a copy of the GNU General Public License
- X-- along with this program; if not, write to the Free Software
- X-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X--
- X-- LOG
- X-- $Log: stdmacs.h,v $
- X * Revision 1.1 90/10/06 12:04:47 dvadura
- X * dmake Release, Version 3.6
- X *
- X*/
- X
- X#ifndef MACROS_h
- X#define MACROS_h
- X
- X#if defined(__STDC__) || defined(__TURBOC__)
- X#define ANSI(x) x
- X#else
- X#define ANSI(x) ()
- X#endif
- X
- X#define NIL(p) ((p*)NULL)
- X#define offsetof(type,id) ((size_t)&((type*)NULL)->id)
- X
- X#define FALSE 0
- X#define TRUE 1
- X
- X#endif
- X
- SHAR_EOF
- chmod 0440 common/stdmacs.h || echo "restore of common/stdmacs.h fails"
- echo "x - extracting common/print.mk (Text)"
- sed 's/^X//' << 'SHAR_EOF' > common/print.mk &&
- X# Make a listing of either everything so far, or just the stuff that has
- X# been updated since the last time a printout was made.
- X# The targets are:
- X# print - to print only updated files.
- X# printall - to print entire tree.
- X#
- X# MACROS are:
- X# PRINTER - printer name on which to put output, output
- X# goes to a file if no printer name is given.
- X# PRINTFLAGS - flags to pass to the printer.
- X# PRINTEXCLUDE - substrings in file names not to include in output.
- X
- XGROUPFLAGS :=
- XSEDLIST = _sed_e_flag_'/{ $(PRINTEXCLUDE) }/d'
- XFILIST = $(TMPDIR)/pr$$$$
- XOFILE = $(TMPDIR)/pr$$$$.out
- X
- X.IF $(PRINTEXCLUDE)
- X SEDARGS = $(SEDLIST:s/_sed_e_flag_/-e /)
- X.END
- X
- Xprintall : print_remove_ctl print;
- Xprint_remove_ctl:;@-$(RM) control/print
- X
- Xprint:
- X@[
- X if [ -f control/print ]; then
- X find . -type f -newer control/print -print |\
- X sort -t. +2 +1 -2 |\
- X sed $(SEDARGS) >$(FILIST);
- X if [ -s $(FILIST) ]; then
- X find . -type f -print | sort -t. +2 +1 -2 |\
- X sed $(SEDARGS) >$(FILIST).full;
- X cpr -c -T control/title -N -C `cat $(FILIST).full` >$(OFILE);
- X cpr -c -N `cat $(FILIST)` >> $(OFILE);
- X $(RM) $(FILIST).full;
- X else
- X echo "No modified files since last printing";
- X fi
- X else
- X find . -type f -print | sort -t. +2 +1 -2 |\
- X sed $(SEDARGS) >$(FILIST);
- X if [ -s $(FILIST) ]; then
- X cpr -c -T control/title -N `cat $(FILIST)` >$(OFILE);
- X fi
- X fi
- X
- X if [ -s $(OFILE) ]; then
- X.IF $(PRINTER)
- X $(PRINT) $(PRINTFLAGS) $(OFILE);
- X echo "Listing printed on $(PRINTER)";
- X.IF $(PRINTKEEPTMP) == $(NULL)
- X $(RM) $(OFILE);
- X.END
- X.ELSE
- X echo "Listing can be temporarily found in $(OFILE)";
- X.END
- X fi
- X.IF $(PRINTKEEPTMP) == $(NULL)
- X $(RM) $(FILIST)
- X.END
- X touch control/print;
- X exit 0
- X]
- SHAR_EOF
- chmod 0662 common/print.mk || echo "restore of common/print.mk fails"
- echo "x - extracting common/malloc.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > common/malloc.c &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/common/RCS/malloc.c,v 1.1 90/10/06 12:04:56 dvadura Exp $
- X-- SYNOPSIS -- debugging version of malloc
- X--
- X-- DESCRIPTION
- X-- malloc for debugging -- allocates via sbrk and tracks stuff, does diag
- X-- dump if things appear to be screwed up. This code is taken from a
- X-- malloc package off the net. By the time I got it the original authors
- X-- name had disappeared. This file can be used by anyone for any
- X-- purpose, since it is originally from usenet, hence the missing
- X-- copyright notice.
- X--
- X-- AUTHOR
- X-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
- X-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
- X--
- X-- LOG
- X-- $Log: malloc.c,v $
- X * Revision 1.1 90/10/06 12:04:56 dvadura
- X * dmake Release, Version 3.6
- X *
- X*/
- X
- X#ifdef DBUG
- X
- X#include <signal.h>
- X#include "extern.h"
- X#include "alloc.h"
- X#include "db.h"
- X
- Xextern char *sbrk();
- Xextern char etext[];
- Xextern char edata[];
- Xextern char end[];
- X
- Xvoid
- XMy_free( ptr, fil, line )/*
- X===========================
- X A routine that check the freeing of NULL pointers. */
- Xchar *ptr;
- Xchar *fil;
- Xint line;
- X{
- X#ifdef DB_MALLOC
- X _malldstr( "free: file:" );
- X _malldstr( fil );
- X _malldstr( " line: " );
- X _dbdumpint( line );
- X _malldstr( " :: " );
- X#endif
- X
- X if( ptr == NIL( char ) )
- X Fatal( "Freeing NIL pointer" );
- SHAR_EOF
- echo "End of part 22"
- echo "File common/malloc.c is continued in part 23"
- echo "23" > s2_seq_.tmp
- exit 0
-
-